package circularQueue;

// 模拟实现循环队列的功能
// 使用size进行记录
// 在数组中方进行存储


public class MyCircularQueue1 {
    // 定义数组 + usedSize
    public int[] array;
    public int usedSize;

    // 定义队头、队尾的下标---注意这里所定义的只是下标而已！！！
    public int front;
    public int rear;

    public MyCircularQueue1(int k) {
        // 进行数组初始化：数组前加一个this比较好！
        //array = new int[k];

        this.array = new int[k];
    }

    // 入队：判空+操作No!! == 其实是进行判满
    public boolean enQueue(int value) {
        /*if(isEmpty()) {
            // 为空
            this.front = value;
            this.rear = value;
            array[usedSize++] = value; // 先用后加
            return true;
        }else {
            this.rear = value;
            array[usedSize] = value;
            usedSize = (usedSize+1) % array.length;
            return true;
        }
        // 默认就是false*/

        if(isFull()) {
            // 如果要进行判满 就要变换队头和队尾
            return false;
        }
        // 这里不对！！
        /*this.array[front] = value;
        this.array[rear] = value;*/

        // 此处对队头不用赋值，因为此时rear==front，随便赋值一个就代表另一个也会被改变！！！
        this.array[rear] = value;
        // 赋值之后rear下标要有变化，但是不是直接++！！
        // 注意：入队过程中：当入队完成后是rear往后挪动了一个下标位置！！！
        this.rear = (this.rear+1)%array.length;
        this.usedSize++;
        return true;
    }

    // 进行出队（删除队头）
    public boolean deQueue() {
        //判空 + 操作
        if(isEmpty()) {
            // 空就返回-1
            return false;
        }
        //这一步是错误的，因为这个操作其实只是给现在的队头重新赋值了而已，但是实际目的是：front下标走到下一个！！不管当前元素
        //this.array[front] = array[(this.front+1) % array.length];
        this.front = (this.front+1) % array.length; // 同样注意这里！
        this.usedSize--;
        return true;
    }

    // 拿到队头不删除
    public int Front() {
        // 注意判空！！
        if(isEmpty()) {
            return -1; // OJ上返回-1 其他可以抛异常！！
        }
        return this.array[front];
    }

    // 拿到队尾
    public int Rear() {
        // 注意判空！！
        if(isEmpty()) {
            return -1; // OJ上返回-1 其他可以抛异常！！
        }
        // 这里依旧是错误的
        //return this.array[rear];

        // 理由即修改如下：
        // 注意：入队过程中：当入队完成后是rear往后挪动了一个下标位置！！！
        // 所以拿到队尾是要让index在实际rear之前一位
        //int index = (rear==0)?(array.length-1):(rear-1);
        //return this.array[index];
        // 或者是
         return this.array[(this.rear + array.length-1)% array.length];
    }

    // 进行判空
    public boolean isEmpty() {
        return (0 == this.usedSize);
    }

    // 进行判满
    public boolean isFull() {
        return (array.length == this.usedSize);
    }

    // 进行大小查找
    public int getSize() {
        return this.usedSize;
    }

    // 模拟一个打印操作：实际上没有这个方法
    public void print() {
        for (int i=this.front; i<this.rear; i++) { //注意循环条件！！！不是从0开始！！！
            System.out.print(this.array[i] + " ");
        }
        System.out.println();
    }
}